from yacs.config import CfgNode as CN
# CfgNode 就像一个可以嵌套的字典，可以非常方便地组织层次化的配置信息。

# -----------------------------------------------------------------------------
# Convention about Training / Test specific parameters
# -----------------------------------------------------------------------------
# Whenever an argument can be either used for training or for testing, the
# corresponding name will be post-fixed by a _TRAIN for a training parameter,

# -----------------------------------------------------------------------------
# Config definition
# -----------------------------------------------------------------------------

# 这个配置文件中所有配置项的根节点
_C = CN()


# -----------------------------------------------------------------------------
# MODEL
# -----------------------------------------------------------------------------

_C.MODEL = CN()
# Using cuda or cpu for training
_C.MODEL.DEVICE = "cuda"
# ID number of GPU
_C.MODEL.DEVICE_ID = '0'
# Name of backbone 决定模型结构
_C.MODEL.NAME = 'resnet50'
# Last stride of backbone
_C.MODEL.LAST_STRIDE = 1
# Path to pretrained model of backbone
_C.MODEL.PRETRAIN_PATH = ''

# Use ImageNet pretrained model to initialize backbone or use self trained model to initialize the whole model
# Options: 'imagenet' , 'self' , 'finetune' 决定权重初始化
_C.MODEL.PRETRAIN_CHOICE = 'imagenet'

# If train with BNNeck, options: 'bnneck' or 'no'
_C.MODEL.NECK = 'bnneck'
# If train loss include center loss, options: 'yes' or 'no'. Loss with center loss has different optimizer configuration 该参数用于让同类内部特征聚集
_C.MODEL.IF_WITH_CENTER = 'no'
# softmax只保证不同类别可分，不保证同类别内部特征聚集
_C.MODEL.ID_LOSS_TYPE = 'softmax'
# 这两个weight决定了在最终模型的总损失占比
_C.MODEL.ID_LOSS_WEIGHT = 1.0
_C.MODEL.TRIPLET_LOSS_WEIGHT = 1.0

_C.MODEL.METRIC_LOSS_TYPE = 'triplet'
# If train with multi-gpu ddp mode, options: 'True', 'False'
_C.MODEL.DIST_TRAIN = False
# If train with soft triplet loss, options: 'True', 'False'
_C.MODEL.NO_MARGIN = True
# If train with label smooth, options: 'on', 'off'
_C.MODEL.IF_LABELSMOOTH = 'on'
# If train with arcface loss, options: 'True', 'False'
_C.MODEL.COS_LAYER = False

# Transformer setting
_C.MODEL.DROP_PATH = 0.1
_C.MODEL.DROP_OUT = 0.0
_C.MODEL.ATT_DROP_RATE = 0.0
_C.MODEL.TRANSFORMER_TYPE = 'None'
_C.MODEL.STRIDE_SIZE = [16, 16]

# JPM Parameter
_C.MODEL.JPM = False
_C.MODEL.SHIFT_NUM = 5
_C.MODEL.SHUFFLE_GROUP = 2
_C.MODEL.DEVIDE_LENGTH = 4
_C.MODEL.RE_ARRANGE = True

# SIE Parameter
_C.MODEL.SIE_COE = 3.0
_C.MODEL.SIE_CAMERA = False
_C.MODEL.SIE_VIEW = False

# -----------------------------------------------------------------------------
# INPUT
# -----------------------------------------------------------------------------

_C.INPUT = CN()
# Size of the image during training
_C.INPUT.SIZE_TRAIN = [384, 128]
# Size of the image during test
_C.INPUT.SIZE_TEST = [384, 128]
# Random probability for image horizontal flip 随机水平翻转概率
_C.INPUT.PROB = 0.5
# Random probability for random erasing 随机擦除概率
_C.INPUT.RE_PROB = 0.5
# Values to be used for image normalization
_C.INPUT.PIXEL_MEAN = [0.485, 0.456, 0.406]
# Values to be used for image normalization
_C.INPUT.PIXEL_STD = [0.229, 0.224, 0.225]
# Value of padding size
_C.INPUT.PADDING = 10

# -----------------------------------------------------------------------------
# Dataset
# -----------------------------------------------------------------------------

_C.DATASETS = CN()
# List of the dataset names for training, as present in paths_catalog.py
_C.DATASETS.NAMES = ('market1501')
# Root directory where datasets should be used (and downloaded if not found)
_C.DATASETS.ROOT_DIR = ('../data')


# -----------------------------------------------------------------------------
# DataLoader
# -----------------------------------------------------------------------------

_C.DATALOADER = CN()
# Number of data loading threads
_C.DATALOADER.NUM_WORKERS = 8
# Sampler for data loading PK采样
_C.DATALOADER.SAMPLER = 'softmax'
# Number of instance for one batch  在一个批次中，为每个身份 (ID) 采样的实例 (instance/image) 数量
_C.DATALOADER.NUM_INSTANCE = 16

# ---------------------------------------------------------------------------- #
# Solver
# ---------------------------------------------------------------------------- #

_C.SOLVER = CN()
# Name of optimizer
_C.SOLVER.OPTIMIZER_NAME = "Adam"
# Number of max epoches
_C.SOLVER.MAX_EPOCHS = 100
# Base learning rate
_C.SOLVER.BASE_LR = 3e-4
# Whether using larger learning rate for fc layer  FC(全连接层)为新一层的网络，选择是否调一个更大的学习率给它
_C.SOLVER.LARGE_FC_LR = False
# Factor of learning bias  偏置项学习率的乘法因子
_C.SOLVER.BIAS_LR_FACTOR = 1
# Factor of learning bias
_C.SOLVER.SEED = 1234
# Momentum
_C.SOLVER.MOMENTUM = 0.9
# Margin of triplet loss
_C.SOLVER.MARGIN = 0.3
# Learning rate of SGD to learn the centers of center loss
_C.SOLVER.CENTER_LR = 0.5
# Balanced weight of center loss
_C.SOLVER.CENTER_LOSS_WEIGHT = 0.0005

# 总损失 = 数据损失 + 惩罚项
# Total Loss = Data Loss (e.g., Cross-Entropy) + λ * (所有权重的平方和)

# Settings of weight decay 权重衰减(一种正则化技术)
_C.SOLVER.WEIGHT_DECAY = 0.0005 # 权重衰减系数即λ
_C.SOLVER.WEIGHT_DECAY_BIAS = 0.0005 # 偏置项衰减系数

# decay rate of learning rate
_C.SOLVER.GAMMA = 0.1
# decay step of learning rate 在40轮的时候,lr = lr*0.1;在70轮的时候,lr = lr*0.1;
_C.SOLVER.STEPS = (40, 70)
# warm up factor 在训练刚开始的几个epoch,让lr从很小的值逐渐增长到设定的base_lr
_C.SOLVER.WARMUP_FACTOR = 0.01 # 开始的lr为base_lr*0.01
#  warm up epochs 预热轮数
_C.SOLVER.WARMUP_EPOCHS = 5 
# method of warm up, option: 'constant','linear'
_C.SOLVER.WARMUP_METHOD = "linear" # 线性提高lr

# 标准的Softmax损失函数只要求模型能将不同类别分开，但它不强制要求同类特征更紧凑、异类特征更疏远。
# 在基于余弦的损失函数中设置的角度或余弦边界值 (margin)
_C.SOLVER.COSINE_MARGIN = 0.5
# 在基于余弦的损失函数中设置的缩放因子 (scale factor)。
_C.SOLVER.COSINE_SCALE = 30

# epoch number of saving checkpoints 每10轮保存一个模型快照
_C.SOLVER.CHECKPOINT_PERIOD = 10
# iteration of display training log 每100轮打印一个日志
_C.SOLVER.LOG_PERIOD = 100
# epoch number of validation 每10轮用测试集测一下模型效果
_C.SOLVER.EVAL_PERIOD = 10
# Number of images per batch
# This is global, so if we have 8 GPUs and IMS_PER_BATCH = 128, each GPU will
# contain 16 images per batch
_C.SOLVER.IMS_PER_BATCH = 64

# ---------------------------------------------------------------------------- #
# TEST
# ---------------------------------------------------------------------------- #

_C.TEST = CN()
# Number of images per batch during test
_C.TEST.IMS_PER_BATCH = 128
# If test with re-ranking, options: 'True','False'
_C.TEST.RE_RANKING = False
# Path to trained model
_C.TEST.WEIGHT = ""
# Which feature of BNNeck to be used for test, before or after BNNneck, options: 'before' or 'after'
_C.TEST.NECK_FEAT = 'after'
# Whether feature is nomalized before test, if yes, it is equivalent to cosine distance
_C.TEST.FEAT_NORM = 'yes'

# Name for saving the distmat after testing.
_C.TEST.DIST_MAT = "dist_mat.npy"
# Whether calculate the eval score option: 'True', 'False' 是否评估计算(比如算Rank-1，Rank-5)
_C.TEST.EVAL = False

# ---------------------------------------------------------------------------- #
# Misc options
# ---------------------------------------------------------------------------- #
# Path to checkpoint and saved log of trained model

_C.OUTPUT_DIR = ""
